/**
 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

class jsvars {
    static global = JSRuntime.getGlobal();
    static gtest_env = JSRuntime.getPropertyJSValue(jsvars.global, "gtest_env");

    static m = JSRuntime.getPropertyJSValue(jsvars.gtest_env, "module");
};

class jscall {
    static _init = JSRuntime.__initJSCallClass("Ljscall;")
    native static num$(top: JSValue, qname: String, a0: double, a1: double) : double;
};

class jsnew {
    static _init = JSRuntime.__initJSNewClass("Ljsnew;")
    native static $(top: JSValue, qname: String, a0: double, a1: double) : JSValue
    native static $(top: JSValue, qname: String) : JSValue;
};

% @integral_primitives.each do |primitive|
function jscall_<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;
    let res = jscall.num$(jsvars.m, ".EvaluateNumber", v0, v1);
    if (res == <%= primitive.getSum() %>) {
        return 0;
    } else {
        return 1;
    }
}

function jsnew_getproperty<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;;
    let res_obj = jsnew.$(jsvars.m, ".ExampleClass", v0, v1);
    let res_get_v0 = JSRuntime.getPropertyDouble(res_obj, "v0");
    let res_get_v1 = JSRuntime.getPropertyDouble(res_obj, "v1");

    if (res_get_v0 == v0 && res_get_v1 == v1) {
        return 0;
    } else {
        return 1;
    }
}

function jsnew_setproperty<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;;
    let res_obj = jsnew.$(jsvars.m, ".ClassWithEmptyConstructor");
    JSRuntime.setPropertyDouble(res_obj, "v0", v0);
    JSRuntime.setPropertyDouble(res_obj, "v1", v1);
    // TODO(itrubachev) enable it after interop upgrade
    // let test_js = JSRuntime.getPropertyJSValue(res_obj, "varify_properties");
    // let check_js = jscall.num$(res_obj, ".varify_properties", v0, v1);
    // if (check_js == 1) {
    //     return 1;
    // }
    let res_get_v0 = JSRuntime.getPropertyDouble(res_obj, "v0");
    let res_get_v1 = JSRuntime.getPropertyDouble(res_obj, "v1");

    if (res_get_v0 == v0 && res_get_v1 == v1) {
        return 0;
    } else {
        return 1;
    }
}

function jscall_static_method_<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;
    let res = jscall.num$(jsvars.m, ".ExampleClass.EvaluateNumber", v0, v1);
    if (res == <%= primitive.getSum() %>) {
        return 0;
    } else {
        return 1;
    }
}

% end

% @float_primitives.each do |primitive|
function jscall_<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;
    let res = jscall.num$(jsvars.m, ".ExampleClass.EvaluateNumber", v0, v1);
    if (abs(res - <%= primitive.getSum() %>) < 0.000001) {
        return 0;
    } else {
        return 1;
    }
}

function jsnew_getproperty<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;;
    let res_obj = jsnew.$(jsvars.m, ".ExampleClass", v0, v1);
    let res_get_v0 = JSRuntime.getPropertyDouble(res_obj, "v0");
    let res_get_v1 = JSRuntime.getPropertyDouble(res_obj, "v1");

    if (abs(res_get_v0 - v0) < 0.000001 && abs(res_get_v1 - v1) < 0.000001) {
        return 0;
    } else {
        return 1;
    }
}

function jsnew_setproperty<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;;
    let res_obj = jsnew.$(jsvars.m, ".ClassWithEmptyConstructor");
    JSRuntime.setPropertyDouble(res_obj, "v0", v0);
    JSRuntime.setPropertyDouble(res_obj, "v1", v1);
    let res_get_v0 = JSRuntime.getPropertyDouble(res_obj, "v0");
    let res_get_v1 = JSRuntime.getPropertyDouble(res_obj, "v1");

    if (res_get_v0 == v0 && res_get_v1 == v1) {
        return 0;
    } else {
        return 1;
    }
}

function jscall_static_method_<%= primitive.getName() %>(): int {
    let v0: <%= primitive.getName() %> = <%= primitive.getMin() %>;
    let v1: <%= primitive.getName() %> = <%= primitive.getMax() %>;
    let res = jscall.num$(jsvars.m, ".ExampleClass.EvaluateNumber", v0, v1);
    if (abs(res - <%= primitive.getSum() %>) < 0.000001) {
        return 0;
    } else {
        return 1;
    }
}

% end
